package com.ruoyi.energize.controller;

import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.energize.domain.DeviceInfo;
import com.ruoyi.energize.domain.SeriesVo;
import com.ruoyi.energize.service.IDeviceInfoService;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.energize.domain.YancaoStoreDailySalesReport;
import com.ruoyi.energize.service.IYancaoStoreDailySalesReportService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 门店日销售报表Controller
 *
 * @author ruoyi
 * @date 2023-05-25
 */

@RestController
@RequestMapping("/energize/daliySalesReport")
@Component //使spring管理
public class YancaoStoreDailySalesReportController extends BaseController
{
    @Autowired
    private IYancaoStoreDailySalesReportService yancaoStoreDailySalesReportService;
    @Autowired
    private IDeviceInfoService deviceInfoService;
    /**
     * 查询门店日销售报表列表
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:list')")
    @GetMapping("/list")
    public TableDataInfo list(YancaoStoreDailySalesReport yancaoStoreDailySalesReport, DeviceInfo deviceInfo)
    {
        //查询满足条件的门店列表信息
        if(yancaoStoreDailySalesReport.getStoreId()!=null && yancaoStoreDailySalesReport.getStoreId()>0){
            deviceInfo.setId(yancaoStoreDailySalesReport.getStoreId().longValue());
        }
        List<DeviceInfo> deviceInfoList = deviceInfoService.selectDeviceInfoList(deviceInfo);
        List<Integer> storeIdList=new ArrayList<>();
        List<YancaoStoreDailySalesReport> list=new ArrayList<>();
        if(!deviceInfoList.isEmpty() && deviceInfoList.size()>0){
            for (DeviceInfo deviceInfo1:deviceInfoList){
                storeIdList.add(Math.toIntExact(deviceInfo1.getId()));
            }
            yancaoStoreDailySalesReport.setStoreIdList(storeIdList);
            startPage();
            list = yancaoStoreDailySalesReportService.selectYancaoStoreDailySalesReportList(yancaoStoreDailySalesReport);
            return getDataTable(list);
        }else{
            return getDataTable(list);
        }
    }

    /**
     * 导出门店日销售报表列表
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:export')")
    @Log(title = "门店日销售报表", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, YancaoStoreDailySalesReport yancaoStoreDailySalesReport)
    {
        List<YancaoStoreDailySalesReport> list = yancaoStoreDailySalesReportService.selectYancaoStoreDailySalesReportList(yancaoStoreDailySalesReport);
        ExcelUtil<YancaoStoreDailySalesReport> util = new ExcelUtil<YancaoStoreDailySalesReport>(YancaoStoreDailySalesReport.class);
        util.exportExcel(response, list, "门店日销售报表数据");
    }

    /**
     * 获取门店日销售报表详细信息
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(yancaoStoreDailySalesReportService.selectYancaoStoreDailySalesReportById(id));
    }

    /**
     * 新增门店日销售报表
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:add')")
    @Log(title = "门店日销售报表", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody YancaoStoreDailySalesReport yancaoStoreDailySalesReport)
    {
        return toAjax(yancaoStoreDailySalesReportService.insertYancaoStoreDailySalesReport(yancaoStoreDailySalesReport));
    }


    /**
     * 修改门店日销售报表
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:edit')")
    @Log(title = "门店日销售报表", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody YancaoStoreDailySalesReport yancaoStoreDailySalesReport)
    {
        return toAjax(yancaoStoreDailySalesReportService.updateYancaoStoreDailySalesReport(yancaoStoreDailySalesReport));
    }

    /**
     * 删除门店日销售报表
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:remove')")
    @Log(title = "门店日销售报表", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(yancaoStoreDailySalesReportService.deleteYancaoStoreDailySalesReportByIds(ids));
    }

    /**
     * 同步客流数据到门店日销售报表中     *
     * 这个是同步日销售报表中当前所有的数据api
     * */
    //@GetMapping("/syncKeLiuToDataReport")
    public void syncKeLiuToDataReport(){
        //查询出需要同步的数据
        List<YancaoStoreDailySalesReport> yancaoStoreDailySalesReportList=yancaoStoreDailySalesReportService.selectSyncKeLiuData(null);
        //同步到日销售报表中
        if(!yancaoStoreDailySalesReportList.isEmpty() && yancaoStoreDailySalesReportList.size()>0){
            for (YancaoStoreDailySalesReport yancaoStoreDailySalesReport:yancaoStoreDailySalesReportList){
                int i=yancaoStoreDailySalesReportService.updateYancaoStoreDailySalesReport(yancaoStoreDailySalesReport);
                System.out.println("同步客流数据，修改了"+i+"条数据");
            }
        }
    }

    /**
     * 同步客流数据到门店日销售报表中
     * 这个是同步昨天日销售报表相关数据
     * */
    @Scheduled(cron = "0 0 4 * * ?")
    //@GetMapping("/syncYesterdayKeLiuToDataReport")
    public void syncYesterdayKeLiuToDataReport(){
        System.out.println("每日凌晨4点同步昨日客流数据到日销售报表中");
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date today = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 1);
        Date yesterday=calendar.getTime();
        String yesterdayStr=df.format(yesterday);
        //查询出需要同步的数据
        List<YancaoStoreDailySalesReport> yancaoStoreDailySalesReportList=yancaoStoreDailySalesReportService.selectSyncKeLiuData(yesterdayStr);
        //同步到日销售报表中
        if(!yancaoStoreDailySalesReportList.isEmpty() && yancaoStoreDailySalesReportList.size()>0){
            for (YancaoStoreDailySalesReport yancaoStoreDailySalesReport:yancaoStoreDailySalesReportList){
                int i=yancaoStoreDailySalesReportService.updateYancaoStoreDailySalesReport(yancaoStoreDailySalesReport);
                System.out.println("同步客流数据，修改了"+i+"条数据");
            }
        }
    }

    /**
     * 日销售额图表统计
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:list')")
    @GetMapping("/sales")
    public Map<String, Object> sales(YancaoStoreDailySalesReport yancaoStoreDailySalesReport) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        List<YancaoStoreDailySalesReport> avgList=new ArrayList<>();
        List<YancaoStoreDailySalesReport> list=new ArrayList<>();
        List<String> legendDataList= new ArrayList<String>();;//折线图名称
        List<String> xAxisDataList= new ArrayList<String>();;//折线图x列
        List<SeriesVo> seriesVoList=new ArrayList<>();//折线图数据
        SeriesVo seriesVo=new SeriesVo();
        List<String> data=new ArrayList<>();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

        //获取某个时间段所有店每日平均销售总额
        avgList=yancaoStoreDailySalesReportService.selectYancaoStoreDailySalesReportAvgListBydate(yancaoStoreDailySalesReport);
        //获取某个时间段每个店每日销售总额
        list=yancaoStoreDailySalesReportService.selectYancaoStoreDailySalesReportListBydate(yancaoStoreDailySalesReport);
        //整合图表需要用到的数据
        if(!avgList.isEmpty() && avgList.size()>0){
            legendDataList.add("单店平均销售");
            seriesVo.setName("单店平均销售");
            seriesVo.setType("line");
            for (YancaoStoreDailySalesReport yancaoStoreDailySalesReport1:avgList){
                String dateString = formatter.format(yancaoStoreDailySalesReport1.getDate());
                xAxisDataList.add(dateString);
                data.add(String.valueOf(yancaoStoreDailySalesReport1.getTotalSales()));
            }
            seriesVo.setData(data);
            seriesVoList.add((SeriesVo)BeanUtils.cloneBean(seriesVo));
        }
        if(!list.isEmpty() && list.size()>0){
            String storeName="";
            data=new ArrayList<>(xAxisDataList.size());
            for (int i=0;i<xAxisDataList.size();i++){
                data.add(String.valueOf(0));
            }
            System.out.println("data的长度"+data.size());
            for (YancaoStoreDailySalesReport yancaoStoreDailySalesReport1:list){
                if(storeName.isEmpty()){
                    storeName=yancaoStoreDailySalesReport1.getStoreName();
                    seriesVo.setName(storeName);
                    seriesVo.setType("line");
                    legendDataList.add(storeName);
                } else if(!storeName.equals(yancaoStoreDailySalesReport1.getStoreName())){
                    seriesVo.setData(data);
                    seriesVo.setName(storeName);
                    seriesVo.setType("line");
                    seriesVoList.add((SeriesVo)BeanUtils.cloneBean(seriesVo));
                    data=new ArrayList<>(xAxisDataList.size());
                    for (int i=0;i<xAxisDataList.size();i++){
                        data.add(String.valueOf(0));
                    }
                    storeName=yancaoStoreDailySalesReport1.getStoreName();
                    seriesVo.setData(data);
                    seriesVo.setName(storeName);
                    seriesVo.setType("line");
                    legendDataList.add(storeName);
                }

                //遍历日期来显示对应的数据，在正确的时间段上
                for (int i=0;i<xAxisDataList.size();i++){
                    if(xAxisDataList.get(i).equals(formatter.format(yancaoStoreDailySalesReport1.getDate()))){
                        data.set(i,String.valueOf(yancaoStoreDailySalesReport1.getTotalSales()));
                    }
                }

            }
            seriesVoList.add((SeriesVo)BeanUtils.cloneBean(seriesVo));
        }
        Map<String, Object> res = new HashMap();
        res.put("legendDataList",legendDataList);
        res.put("xAxisDataList",xAxisDataList);
        res.put("seriesVoList",seriesVoList);
        return res;
    }

    /**
     * 周销售额图表统计
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:list')")
    @GetMapping("/listWeekDaliySales")
    public Map<String, Object> listWeekDaliySales(YancaoStoreDailySalesReport yancaoStoreDailySalesReport) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        List<YancaoStoreDailySalesReport> salesList=new ArrayList<>();//周总销售额列表
        List<YancaoStoreDailySalesReport> unitPriceList=new ArrayList<>();//周客户单价
        List<YancaoStoreDailySalesReport> orderNumList=new ArrayList<>();//周客户订单总数量
        //获取某个时间段总销售额列表按照星期分组求平均销售额
        salesList=yancaoStoreDailySalesReportService.selectWeekSalesAvgListByTime(yancaoStoreDailySalesReport);
        //获取某个时间段客户单价列表按照星期分组求平均客单价
        unitPriceList=yancaoStoreDailySalesReportService.selectWeekUnitPriceAvgListByTime(yancaoStoreDailySalesReport);
        //获取某个时间段客户单价列表按照星期分组求订单量
        orderNumList=yancaoStoreDailySalesReportService.selectWeekOrderNumAvgListByTime(yancaoStoreDailySalesReport);
        Map<String, Object> salesRes=this.makeWeekChartData(salesList);
        Map<String, Object> unitPriceRes=this.makeWeekChartData(unitPriceList);
        Map<String, Object> orderNumRes=this.makeWeekChartData(orderNumList);
        Map<String, Object> res=new HashMap();
        res.put("salesRes",salesRes);
        res.put("unitPriceRes",unitPriceRes);
        res.put("orderNumRes",orderNumRes);
        return res;
    }

    public Map<String, Object> makeWeekChartData(List<YancaoStoreDailySalesReport> list){
        List<String> legendDataList= new ArrayList<String>();;//柱状图名称
        List<String> xAxisDataList= new ArrayList<String>();;//柱状图x列
        List<String> seriesVoList=new ArrayList<>();//柱状图数据
        legendDataList.add("汇总");
        if(!list.isEmpty() && list.size()>0){
            for (YancaoStoreDailySalesReport yancaoStoreDailySalesReport:list){
                xAxisDataList.add(yancaoStoreDailySalesReport.getWeek());
                seriesVoList.add(String.valueOf(yancaoStoreDailySalesReport.getTotalSales()));
            }
        }
        Map<String, Object> res = new HashMap();
        res.put("legendDataList",legendDataList);
        res.put("xAxisDataList",xAxisDataList);
        res.put("seriesVoList",seriesVoList);
        return res;
    }

    /**
     * 月销售额图表统计
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:list')")
    @GetMapping("/listMonthDaliySales")
    public Map<String, Object> listMonthDaliySales(YancaoStoreDailySalesReport yancaoStoreDailySalesReport) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        List<YancaoStoreDailySalesReport> list=new ArrayList<>();//周总销售额列表
        //获取某个时间段总销售额列表按照月分组求平均销售额
        list=yancaoStoreDailySalesReportService.selectMonthSalesAvgListByTime(yancaoStoreDailySalesReport);
        List<String> xAxisDataList= new ArrayList<>();;//柱状图x列
        List<String> salesResSeriesVoList=new ArrayList<>();//柱状图数据
        List<String> unitPriceResSeriesVoList=new ArrayList<>();//柱状图数据
        List<String> orderNumResSeriesVoList=new ArrayList<>();//柱状图数据
        Map<String, Object> res=new HashMap();
        if(!list.isEmpty() && list.size()>0){
            for (YancaoStoreDailySalesReport yancaoStoreDailySalesReport1:list){
                xAxisDataList.add(String.valueOf(yancaoStoreDailySalesReport1.getMonths()));
                salesResSeriesVoList.add(String.valueOf(yancaoStoreDailySalesReport1.getTotalSales()));
                unitPriceResSeriesVoList.add(String.valueOf(yancaoStoreDailySalesReport1.getCustomerUnitPrice()));
                orderNumResSeriesVoList.add(String.valueOf(yancaoStoreDailySalesReport1.getCustomerOrderAmount()));
            }
            res.put("xAxisDataList",xAxisDataList);
            res.put("salesResSeriesVoList",salesResSeriesVoList);
            res.put("unitPriceResSeriesVoList",unitPriceResSeriesVoList);
            res.put("orderNumResSeriesVoList",orderNumResSeriesVoList);
        }
        return res;
    }


    /**
     * 日销售额图表统计
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:list')")
    @GetMapping("/listStoreMonthDaliySales")
    public Map<String, Object> listStoreMonthDaliySales(YancaoStoreDailySalesReport yancaoStoreDailySalesReport) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        //获取某个时间段每个店每日销售总额
        List<YancaoStoreDailySalesReport> list=yancaoStoreDailySalesReportService.selectStoreMonthListBydate(yancaoStoreDailySalesReport);
        Map<String, Object> salesRes=this.makeListStoreMonthDaliySales(list,"sales");
        Map<String, Object> cigaretteRes=this.makeListStoreMonthDaliySales(list,"cigarette");
        Map<String, Object> orderNumRes=this.makeListStoreMonthDaliySales(list,"orderNum");
        Map<String, Object> res=new HashMap();
        res.put("salesRes",salesRes);
        res.put("cigaretteRes",cigaretteRes);
        res.put("orderNumRes",orderNumRes);
        return res;
    }

    //整合页面显示得对应图表数据
    public Map<String,Object> makeListStoreMonthDaliySales( List<YancaoStoreDailySalesReport> list,String name) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        List<String> legendDataList= new ArrayList<String>();;//折线图名称
        List<SeriesVo> seriesVoList=new ArrayList<>();//销售额折线图数据
        List<String> xAxisDataList=new ArrayList<>();//折线图X列数据
        SeriesVo seriesVo=new SeriesVo();
        //整合图表需要用到的数据
        List<String> data=new ArrayList<>();
        if(!list.isEmpty() && list.size()>0){
            List<String> monthsList=new ArrayList<>();
            //第一遍循环 得到所有得日期和门店列表
            for (YancaoStoreDailySalesReport yancaoStoreDailySalesReport1:list){
                monthsList.add(yancaoStoreDailySalesReport1.getMonths());
            }
            //将日期和商户id进行去重并且赋值将不存在得商户数据用零填充
            xAxisDataList=monthsList.stream().distinct().collect(Collectors.toList());//折线图X列数据
            //再次循环 将商户信息按照图表得要求进行返回结果
            String storeName="";
            data=new ArrayList<>();
            //将所有得数据先用零填充，以防有的商户在某一天没有销售额
            for (int i=0;i<xAxisDataList.size();i++){
                data.add(String.valueOf(0));
            }
            for (YancaoStoreDailySalesReport yancaoStoreDailySalesReport1:list){
                if(storeName.isEmpty()){
                    storeName=yancaoStoreDailySalesReport1.getStoreName();
                    seriesVo.setName(storeName);
                    seriesVo.setType("line");
                    legendDataList.add(storeName);
                } else if(!storeName.equals(yancaoStoreDailySalesReport1.getStoreName())){
                    seriesVo.setData(data);
                    seriesVo.setName(storeName);
                    seriesVo.setType("line");
                    seriesVoList.add((SeriesVo)BeanUtils.cloneBean(seriesVo));
                    data=new ArrayList<>(xAxisDataList.size());
                    for (int i=0;i<xAxisDataList.size();i++){
                        data.add(String.valueOf(0));
                    }
                    storeName=yancaoStoreDailySalesReport1.getStoreName();
                    seriesVo.setData(data);
                    seriesVo.setName(storeName);
                    seriesVo.setType("line");
                    legendDataList.add(storeName);
                }

                //遍历日期来显示对应的数据，在正确的时间段上
                for (int i=0;i<xAxisDataList.size();i++){
                    if(xAxisDataList.get(i).equals(yancaoStoreDailySalesReport1.getMonths())){
                        if(name.equals("sales")){
                            data.set(i,String.valueOf(yancaoStoreDailySalesReport1.getTotalSales()));
                        } else if(name.equals("cigarette")){
                            data.set(i,String.valueOf(yancaoStoreDailySalesReport1.getCigaretteSales()));
                        } else if(name.equals("orderNum")){
                            data.set(i,String.valueOf(yancaoStoreDailySalesReport1.getCustomerOrderAmount()));
                        }
                    }
                }

                //当查询出来的数据只有一条数据满足条件时，需要将data值赋值给seriesVo
                if(list.size()==1){
                    seriesVo.setData(data);
                }
            }
            seriesVoList.add((SeriesVo)BeanUtils.cloneBean(seriesVo));

        }

        Map<String, Object> res = new HashMap();
        res.put("legendDataList",legendDataList);
        res.put("xAxisDataList",xAxisDataList);
        res.put("seriesVoList",seriesVoList);
        return res;
    }


    /**
     * 根据日期范围获取到这个范围内非烟，卷烟，含卷烟得订单销售额占比
     * 根据日期范围获取再次期间每个门店的卷烟销售总额
     * @param yancaoStoreDailySalesReport
     * @return
     */
    @PreAuthorize("@ss.hasPermi('energize:daliySalesReport:list')")
    @GetMapping("/listCigaretteDaliySales")
    public Map<String, Object> listCigaretteDaliySales(YancaoStoreDailySalesReport yancaoStoreDailySalesReport) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        //获取某个时间段每个店总卷烟销售总额
        List<YancaoStoreDailySalesReport> list=yancaoStoreDailySalesReportService.selectStoreSalesListBydate(yancaoStoreDailySalesReport);
        //统计某个时间段内非烟订单销售额，含烟订单中纯烟草销售额，含烟订单中不包含烟草销售额
        YancaoStoreDailySalesReport sales=yancaoStoreDailySalesReportService.selectSumSalesBydate(yancaoStoreDailySalesReport);

        Map<String, Object> cigaretteRes=this.makeStoreCigaretteChartData(list);

        SeriesVo seriesNotIncludeCigaretteOrderSalesVo=new SeriesVo();
        SeriesVo seriesCigaretteVo=new SeriesVo();
        SeriesVo seriesIncludeCigaretteNotCigaretteVo=new SeriesVo();
        List<SeriesVo> seriesVoList=new ArrayList<>();
        if(sales!=null){
            seriesNotIncludeCigaretteOrderSalesVo.setName("非烟订单销售额");
            seriesNotIncludeCigaretteOrderSalesVo.setValue(String.valueOf(sales.getNotIncludeCigaretteOrderSales()));
            seriesVoList.add(seriesNotIncludeCigaretteOrderSalesVo);
            seriesCigaretteVo.setName("烟草销售额");
            seriesCigaretteVo.setValue(String.valueOf(sales.getCigaretteSales()));
            seriesVoList.add(seriesCigaretteVo);
            seriesIncludeCigaretteNotCigaretteVo.setName("含烟订单中非烟销售额");
            seriesIncludeCigaretteNotCigaretteVo.setValue(String.valueOf(sales.getIncludeCigaretteOrderSales()));
            seriesVoList.add(seriesIncludeCigaretteNotCigaretteVo);
        }
        Map<String, Object> res=new HashMap();
        res.put("cigaretteRes",cigaretteRes);
        res.put("seriesVoList",seriesVoList);
        return res;
    }

    public Map<String, Object> makeStoreCigaretteChartData(List<YancaoStoreDailySalesReport> list){
        List<String> xAxisDataList= new ArrayList<String>();;//柱状图x列
        List<String> seriesVoList=new ArrayList<>();//柱状图数据
        if(!list.isEmpty() && list.size()>0){
            for (YancaoStoreDailySalesReport yancaoStoreDailySalesReport:list){
                xAxisDataList.add(yancaoStoreDailySalesReport.getStoreName());
                seriesVoList.add(String.valueOf(yancaoStoreDailySalesReport.getCigaretteSales()));
            }
        }
        Map<String, Object> res = new HashMap();
        res.put("xAxisDataList",xAxisDataList);
        res.put("seriesVoList",seriesVoList);
        return res;
    }

}
